Skip to content

Add comprehensive race condition & state conflict xfail test suite#627

Draft
tony wants to merge 3 commits intomasterfrom
tests/race-conditions
Draft

Add comprehensive race condition & state conflict xfail test suite#627
tony wants to merge 3 commits intomasterfrom
tests/race-conditions

Conversation

@tony
Copy link
Copy Markdown
Member

@tony tony commented Feb 6, 2026

Summary

  • Add tests/test_race_conditions.py with 17 tests (15 xfail, 2 passing) documenting every discoverable state conflict in libtmux
  • Covers 5 categories: create-query races, object staleness after external mutation, DX frustrations, query/filter edge cases, and ID recycling after server restart
  • Each xfail test documents one specific failure mode, its root cause, and which layer (tmux C, Python subprocess, libtmux ORM) is responsible

Categories

Category 1 — Create-query races (6 xfail): Two-step "create → query" pattern fails when state changes between the tmux command and the follow-up list query.

Category 2 — Object staleness after external mutation (3 xfail, 1 pass): Cached Python objects become invalid after the underlying tmux object is killed externally. Includes killed session/window/pane access patterns.

Category 3 — DX frustrations (3 xfail, 1 pass): Natural API usage patterns that produce confusing or silent failures — dead server sessions returning [], inconsistent error handling between sessions/windows/panes properties.

Category 4 — Query/filter edge cases (2 xfail): QueryList.filter() with typo field names silently returns empty lists; fetch_obj by mutable keys fails after renames.

Category 5 — ID recycling after server restart (1 xfail): Stale Python refs with recycled $0 IDs silently match wrong objects after server restart.

Test plan

  • uv run pytest tests/test_race_conditions.py -v — 2 passed, 15 xfailed
  • uv run ruff check tests/test_race_conditions.py — no errors
  • uv run mypy tests/test_race_conditions.py — no errors
  • uv run pytest — full suite passes (874 passed, 1 skipped, 15 xfailed)

@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 46.75%. Comparing base (81d55fa) to head (f0435d4).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #627      +/-   ##
==========================================
+ Coverage   46.58%   46.75%   +0.16%     
==========================================
  Files          22       22              
  Lines        2372     2372              
  Branches      390      390              
==========================================
+ Hits         1105     1109       +4     
+ Misses       1098     1096       -2     
+ Partials      169      167       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

tony added 3 commits April 26, 2026 05:07
why: Document known vulnerability where two-step "create → query" pattern
in new_session(), new_window(), and split() can fail if tmux state changes
between the creation command and the subsequent list-* query (#624).

what:
- Add tests/test_race_conditions.py with 6 strict xfail tests
- 3 tests for server crash between create and query (Mode A)
- 3 tests for stale empty list-* response (Mode B)
- All tests are parallel-safe (unique sockets, function-scoped monkeypatch)
- Tests will flip to XPASS when creation methods construct objects directly
  from -P output instead of re-querying
… ID recycling

why: Extend the race condition test suite into a comprehensive almanac
of every discoverable state conflict in libtmux, beyond the initial 6
create-query tests.
what:
- Add Category 2: Object staleness after external mutation
  - Killed session active_window gives raw LibTmuxException
  - Killed session refresh correctly raises TmuxObjectDoesNotExist (passing)
  - Killed window panes gives raw LibTmuxException
  - Dead pane send_keys silently swallows error
- Add Category 3: DX frustrations
  - Dead server sessions silently returns [] (bare except:pass)
  - Context manager rename works correctly (passing positive test)
  - Dead server windows/panes raise raw LibTmuxException (inconsistent)
- Add Category 4: Query/filter edge cases
  - Filter typo field silently returns empty list
  - fetch_obj by mutable session_name fails after rename
- Add Category 5: ID recycling after server restart
  - Stale ref with recycled $0 silently returns wrong session data
…ests

why: #625 (released v0.53.1) eliminated the second list-sessions query
in Server.new_session by parsing session data directly from
'tmux new-session -P -F<format>' output via parse_output(session_stdout).
The two strict-xfail tests in this file that patched
neo.fetch_objs(list_cmd='list-sessions') were unreachable after that
fix and could only XPASS — failing the suite when run with --reruns=0.
what:
- remove test_new_session_server_crash and test_new_session_stale_list
- replace with NOTE comments explaining why and pointing to #625
- new_window/split variants stay; those creation paths still re-query
@tony tony force-pushed the tests/race-conditions branch from 9d931f6 to f0435d4 Compare April 26, 2026 11:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant